package bancosys.tec.services.tools;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import bancosys.tec.utils.reader.URLReaderFactory;

public final class FileUtils {

    private static final String UTF8 = "UTF-8";

    private FileUtils() {
        super();
    }

    private static FileUtils instance = new FileUtils();

    public static FileUtils getInstance() {
        return instance;
    }

    /**
     * Usa a regex padrão, (?i).*\\.xls
     * 
     * @param inputFiles inputFiles
     * @return List de URL
     * @throws IOException IOException
     * @deprecated prefira especificar a regex.
     */
    @Deprecated
    public  List<URL> getFilesToExecute(List<String> inputFiles) throws IOException {
        return this.getFilesToExecute(inputFiles, "(?i).*\\.xls");
    }

    /**
     * Obtém todos os arquivos da lista. Caso algum elemento seja um diretório, varre recursivamente. Apenas arquivos que coincidem com a
     * regex são retornados, em geral para filtrar extenções. Em geral é desejável utilizar a flag (?i) para ignorar case de extenções. Ex.:
     * (?i).*\\.xls
     * 
     * @param inputFiles inputFiles
     * @param fileRegex fileRegex
     * @return List de URL
     * @throws IOException IOException
     */
    public  List<URL> getFilesToExecute(List<String> inputFiles, String fileRegex) throws IOException {
        List<URL> filesToExecute = new ArrayList<URL>();
        for (String inputFile : inputFiles) {

            /*
             * Procurar primeiramente o arquivo no classpath, se ele nao for encontrado procurar um arquivo com o mesmo nome
             */
            URL testInputURL = this.getClass().getClassLoader().getResource(inputFile);
            if (testInputURL == null) {
                File localInputFile = new File(inputFile);
                if (localInputFile.exists()) {
                    testInputURL = localInputFile.toURI().toURL();
                } else {
                    throw new FileNotFoundException("O arquivo " + inputFile + " não foi encontrado!");
                }
            }
            filesToExecute.addAll(URLReaderFactory.getFileReader(testInputURL).getFiles(testInputURL, fileRegex));
        }
        return filesToExecute;
    }

    /**
     * Le o conteudo do arquivo e armazena em uma {@link String}.
     * 
     * @param url url
     * @return o conteudo do script passado como parametro
     * @throws IOException se ocorrer algum erro
     */
    public static String readFileContends(URL url) throws IOException {
        BufferedReader input = new BufferedReader(new InputStreamReader(url.openStream(), UTF8));
        StringBuilder sb = new StringBuilder();
        while (true) {
            int c = input.read();
            if (c == -1) {
                break;
            }
            sb.append((char) c);
        }
        return sb.toString();
    }

    /**
     * Recursivelly removes a directory and its content.
     * 
     * @param dir directory to be removed.
     */
    public static void deltree(final File dir) {
        if (dir == null || !dir.isDirectory()) {
            throw new IllegalArgumentException("Invalid directory: " + dir);
        }
        for (final String fileName : dir.list()) {
            final File file = new File(dir, fileName);
            if (file.isDirectory()) {
                FileUtils.deltree(new File(dir.getPath() + File.separator + fileName));
                file.delete();
            } else if (file.isFile()) {
                file.delete();
            }
        }
        dir.delete();
    }
}
